<script setup>

import {getCurrentInstance, nextTick, onMounted, ref} from "vue";
import {getAiJudgeAndRecommendByPractice, getPracticeDetail} from "../../../../api/user/user.js";
import {fetchEventSource} from "@microsoft/fetch-event-source";
import {ElMessage} from "element-plus";
import hljs from "highlight.js";
import {onBeforeRouteLeave, onBeforeRouteUpdate} from "vue-router";
import {clearChatHistory} from "@/api/ai/studentChatAIApi.js";
let loading = ref(false);
let echartsDom = null;
let nodeList = [[1],[2],[3],[4],[5]]
// 通过 internalInstance.appContext.config.globalProperties 获取全局属性或方法
let internalInstance = getCurrentInstance();
let echarts = internalInstance.appContext.config.globalProperties.$echarts;
// 练习情况评测提示词
let practiceEvaluationTip = ref();
// 练习情况评测
let practiceEvaluation = ref('');
const controller = new AbortController();
const signal = controller.signal;
// 滚动条实例
const scrollbarRef = ref();
// 计数器内部实例
const innerRef = ref();
function dealAnswer(data,answer) {
  let sseData = data;
  sseData = sseData.replaceAll("&#32;", " ").replaceAll("&#92n", "\n")
  answer += sseData;
  return answer;
}
onBeforeRouteLeave((to, from, next) => {
  controller.abort()
  next()
})
onBeforeRouteUpdate((to, from, next) => {
  controller.abort()
  next()
})
async function setScrollToBottom() {
  // 注意：需要通过 nextTick 以等待 DOM 更新完成
  await nextTick()
  const max = innerRef.value.clientHeight
  scrollbarRef.value.setScrollTop(max)
}
// 将md转化为html
function mdToHtml(content,callback) {
  import('markdown-it').then(module => {
    const md = module.default('commonmark', {
      highlight: function (str, lang) {
        if (lang && hljs.getLanguage(lang)) {
          try {
            return '<pre class="hljs"><code>' +
                hljs.highlight(lang, str, true).value +
                '</code></pre>';
          } catch (__) {}
        }

        return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
      }
    });
    callback(md.render(content));
  });
}
// 用户进入页面时 需要清空和ai对话的历史记录
clearChatHistory();
getAiJudgeAndRecommendByPractice().then(res => {
    practiceEvaluationTip.value = res.data;
    // fetch请求方法控制器
    let answer = '';
    let nowHtml = '';
    setInterval(async () => {
      if ( nowHtml.length > practiceEvaluation.value.length ) {
        let nowLen = practiceEvaluation.value.length;
        if ( nowHtml[nowLen] === '<' ) {
          while ( nowHtml[nowLen] !== '>' ) {
            nowLen ++;
          }
        }
        practiceEvaluation.value = nowHtml.slice(0,nowLen+1);
        await setScrollToBottom()
      }
    },70)
    fetchEventSource("/api/aiChat/chat?question="+practiceEvaluationTip.value,{
      method: 'GET',
      headers: {
        'content-type': 'application/json',
        'token': localStorage.getItem("token")
      },
      signal: signal,
      openWhenHidden: true,
      onmessage(event) {
        answer = dealAnswer(event.data,answer)
        if ( event.data === '&#92n[DONE]') {
          // 发送完成结束对话
          controller.abort();
          return;
        }
        mdToHtml(answer,(html)=>{
          nowHtml = html;
        })
      },
      onclose(event) {
        controller.abort();
      },
      onerror(event) {
        ElMessage.error("对话失败，请重试");
        controller.abort();
      }
    });
    loading.value = false;
  }
)
onMounted(async () => {
  await nextTick(() => {
    echartsDom = document.querySelector('.echarts');
    getPracticeDetail().then(res=> {
      let idx = 0;
      const myChart = echarts.init(echartsDom);
      let width = myChart.getWidth();
      let height = myChart.getHeight();
      const data = [
        {
          name: '练习情况',
          type: 0,
          fixed: true,
          x: myChart.getWidth() / 2,
          y: myChart.getHeight() / 2,
          symbolSize: 20,
          id: 0
        },
        {
          name: '单选',
          fixed: true,
          type: 0,
          x: Math.floor(Math.random() * width),
          y: Math.floor(Math.random() * height),
          symbolSize: 15,
          id: 1
        },
        {
          name: '多选',
          fixed: true,
          type: 1,
          x: Math.floor(Math.random() * width),
          y: Math.floor(Math.random() * height),
          symbolSize: 15,
          id: 2
        },
        {
          name: '判断',
          fixed: true,
          type: 2,
          x: Math.floor(Math.random() * width),
          y: Math.floor(Math.random() * height),
          symbolSize: 15,
          id: 3
        },
        {
          name: '填空',
          fixed: true,
          type: 3,
          x: Math.floor(Math.random() * width),
          y: Math.floor(Math.random() * height),
          symbolSize: 15,
          id: 4
        },
        {
          name: '简答',
          fixed: true,
          type: 4,
          x: Math.floor(Math.random() * width),
          y: Math.floor(Math.random() * height),
          symbolSize: 15,
          id: 5
        },
      ];
      const edges = [{
        source: 0,
        target: 1
      },{
        source: 0,
        target: 2
      },{
        source: 0,
        target: 3
      },{
        source: 0,
        target: 4
      },{
        source: 0,
        target: 5
      }];
      const option = {
        animationDurationUpdate: 1500,//数据更新动画的时长。
        animationEasingUpdate: 'quinticInOut',//数据更新动画的缓动效果。
        // 鼠标悬停显示数据
        tooltip: {
          trigger: 'item',
          backgroundColor: '#fff', // 悬浮框背景色
          borderColor: '#000', // 悬浮框边框颜色
          borderWidth: 1, // 悬浮框边框宽度
          textStyle: { // 悬浮框文字样式
            color: '#000',
            fontSize: 12
          }
        },
        grid: {
          bottom: '50%'
        },
        series: [
          {
            type: 'graph',
            layout: 'force',
            animation: false,
            data: data,
            itemStyle: {//配置节点的颜色已及尺寸
              normal: {
                color: function (params) {
                  console.log(params)
                  var colorList = ['red', 'orange', 'green', 'pink', 'purple'];
                  return params.data.id === 0 ? 'blue' : colorList[params.data.type]
                },

              }
            },
            force: {
              repulsion: 100,
              edgeLength: 5
            },
            edges: edges
          }
        ]
      };
      setInterval(function () {
        if ( idx >= res.data.length ) {
          return;
        }
        let len = data.length;
        data.push({
          id: len,
          type: res.data[idx].type,
          name: res.data[idx].name,
          symbolSize: 10
        })
        // 获取是什么类型的题目
        var group = res.data[idx].type;
        // 获取group对应数组长度
        let groupLen = nodeList[group].length;
        // 在0~group中随机生成一个数
        var index = Math.round(Math.random() * (groupLen - 1));
        edges.push({
          source: nodeList[group][index],
          target: len
        });
        myChart.setOption({
          series: [
            {
              roam: true,
              data: data,
              edges: edges
            }
          ]
        });
        idx ++;
    },400)
      myChart.setOption(option);
    })
  })
})
</script>

<template>
  <div class="common-area">
    <el-container class="container-area">
      <div class="box">
        <div class="echarts"></div>
        <el-divider direction="vertical" class="divider"></el-divider>
      </div>
      <div
        v-loading="loading"
        element-loading-text="Loading..."
        class="ai-recommend">
        <div class="ai-title">📚AI总结及推荐结果如下：</div>
        <div v-html="practiceEvaluation" style="font-size: 15px"></div>
      </div>
    </el-container>
  </div>
</template>

<style lang="less" scoped>
.common-area {
  width: 100%;
  height: 700px;
  .container-area {
    width: 100%;
    height: 100%;
    display: flex;
    .box {
      width: 70%;
      height: 100%;
      display: flex;
      .echarts {
        width: 100%;
        height: 100%;
      }
      .divider {
        margin-right: 10px;
        height: 100%;
      }
    }
    .ai-recommend {
      flex: 1;
      .ai-title {
        font-weight: bold;
        margin-top: 13px;
        width: 100%
      }
    }
  }
}
</style>